home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / t_unix / j109lxa4.tar / tcpin.c < prev    next >
C/C++ Source or Header  |  1994-06-04  |  24KB  |  911 lines

  1. /* Process incoming TCP segments. Page number references are to ARPA RFC-793,
  2.  * the TCP specification.
  3.  *
  4.  * Copyright 1991 Phil Karn, KA9Q
  5.  *
  6.  * Mods by PA0GRI (access control)
  7.  * Copyright 1992 Gerard J van der Grinten, PA0GRI
  8.  */
  9. #include "global.h"
  10. #include "config.h"
  11. #include "timer.h"
  12. #include "mbuf.h"
  13. #include "netuser.h"
  14. #include "internet.h"
  15. #include "tcp.h"
  16. #include "icmp.h"
  17. #include "iface.h"
  18. #include "ip.h"
  19.  
  20. static void update __ARGS((struct tcb *tcb,struct tcp *seg,int16 length));
  21. static void proc_syn __ARGS((struct tcb *tcb,char tos,struct tcp *seg));
  22. static void add_reseq __ARGS((struct tcb *tcb,char tos,struct tcp *seg,
  23.     struct mbuf *bp,int16 length));
  24. static void get_reseq __ARGS((struct tcb *tcb,char *tos,struct tcp *seq,
  25.     struct mbuf **bp,int16 *length));
  26. static int trim __ARGS((struct tcb *tcb,struct tcp *seg,struct mbuf **bpp,
  27.     int16 *length));
  28. static int in_window __ARGS((struct tcb *tcb,int32 seq));
  29.  
  30. /* This function is called from IP with the IP header in machine byte order,
  31.  * along with a mbuf chain pointing to the TCP header.
  32.  */
  33. void
  34. tcp_input(iface,ip,bp,rxbroadcast)
  35. struct iface *iface;    /* Incoming interface (ignored) */
  36. struct mbuf *bp;    /* Data field, if any */
  37. struct ip *ip;        /* IP header */
  38. int rxbroadcast;    /* Incoming broadcast - discard if true */
  39. {
  40.     struct tcb *ntcb;
  41.     register struct tcb *tcb;    /* TCP Protocol control block */
  42.     struct tcp seg;            /* Local copy of segment header */
  43.     struct connection conn;        /* Local copy of addresses */
  44.     struct pseudo_header ph;    /* Pseudo-header for checksumming */
  45.     int hdrlen;            /* Length of TCP header */
  46.     int16 length;
  47.  
  48.     if(bp == NULLBUF)
  49.         return;
  50.  
  51.     tcpInSegs++;
  52.     if(rxbroadcast){
  53.         /* Any TCP packet arriving as a broadcast is
  54.          * to be completely IGNORED!!
  55.          */
  56.         free_p(bp);
  57.         return;
  58.     }
  59.     length = ip->length - IPLEN - ip->optlen;
  60.     ph.source = ip->source;
  61.     ph.dest = ip->dest;
  62.     ph.protocol = ip->protocol;
  63.     ph.length = length;
  64.     if(cksum(&ph,bp,length) != 0){
  65.         /* Checksum failed, ignore segment completely */
  66.         tcpInErrs++;
  67.         free_p(bp);
  68.         return;
  69.     }
  70.     /* Form local copy of TCP header in host byte order */
  71.     if((hdrlen = ntohtcp(&seg,&bp)) < 0){
  72.         /* TCP header is too small */
  73.         free_p(bp);
  74.         return;
  75.     }
  76.     length -= hdrlen;
  77.  
  78.     /* Fill in connection structure and find TCB */
  79.     conn.local.address = ip->dest;
  80.     conn.local.port = seg.dest;
  81.     conn.remote.address = ip->source;
  82.     conn.remote.port = seg.source;
  83.     
  84.     if((tcb = lookup_tcb(&conn)) == NULLTCB){
  85.         /* If memory low, reject it - WG7J */
  86.         /* If this segment doesn't carry a SYN, reject it */
  87. #ifdef UNIX
  88.         if(!seg.flags.syn){
  89. #else
  90.         if((availmem() < Memthresh) || !seg.flags.syn){
  91. #endif
  92.             free_p(bp);
  93.             reset(ip,&seg);
  94.             return;
  95.         }
  96. #ifdef  TCPACCESS
  97.         if(tcp_check(TCPaccess,ip->source,seg.dest) != 0 ) {
  98.             free_p(bp);
  99.             reset(ip,&seg);
  100.             return;
  101.         }
  102. #endif
  103.         /* See if there's a TCP_LISTEN on this socket with
  104.          * unspecified remote address and port
  105.          */
  106.         conn.remote.address = 0;
  107.         conn.remote.port = 0;
  108.         /* NOS currently always listens on unspecified addresses ! - WG7J */
  109.         conn.local.address = 0;
  110.         if((tcb = lookup_tcb(&conn)) == NULLTCB){
  111. #ifdef notdef
  112.             /* Nope, try unspecified local address too */
  113.             conn.local.address = 0;
  114.             if((tcb = lookup_tcb(&conn)) == NULLTCB){
  115. #endif
  116.                 /* No LISTENs, so reject */
  117.                 free_p(bp);
  118.                 reset(ip,&seg);
  119.                 return;
  120. #ifdef notdef
  121.             }
  122. #endif
  123.         }
  124.         /* We've found an server listen socket, so clone the TCB */
  125.         if(tcb->flags.clone){
  126.             ntcb = (struct tcb *)mallocw(sizeof (struct tcb));
  127.             ASSIGN(*ntcb,*tcb);
  128.             tcb = ntcb;
  129.             tcb->timer.arg = tcb;
  130.             /* Put on list */
  131.             tcb->next = Tcbs;
  132.             Tcbs = tcb;
  133.         }
  134.         /* Put all the socket info into the TCB */
  135.         tcb->conn.local.address = ip->dest;
  136.         tcb->conn.remote.address = ip->source;
  137.         tcb->conn.remote.port = seg.source;
  138.     }
  139.     tcb->flags.congest = ip->flags.congest;
  140.     /* Do unsynchronized-state processing (p. 65-68) */
  141.     switch(tcb->state){
  142.     case TCP_CLOSED:
  143.         free_p(bp);
  144.         reset(ip,&seg);
  145.         return;
  146.     case TCP_LISTEN:
  147.         if(seg.flags.rst){
  148.             free_p(bp);
  149.             return;
  150.         }
  151.         if(seg.flags.ack){
  152.             free_p(bp);
  153.             reset(ip,&seg);
  154.             return;
  155.         }
  156.         if(seg.flags.syn){
  157.             /* (Security check is bypassed) */
  158.             /* page 66 */
  159.             proc_syn(tcb,ip->tos,&seg);
  160.             send_syn(tcb);
  161.             setstate(tcb,TCP_SYN_RECEIVED);        
  162.             if(length != 0 || seg.flags.fin) {
  163.                 /* Continue processing if there's more */
  164.                 break;
  165.             }
  166.             tcp_output(tcb);
  167.         }
  168.         free_p(bp);    /* Unlikely to get here directly */
  169.         return;
  170.     case TCP_SYN_SENT:
  171.         if(seg.flags.ack){
  172.             if(!seq_within(seg.ack,tcb->iss+1,tcb->snd.nxt)){
  173.                 free_p(bp);
  174.                 reset(ip,&seg);
  175.                 return;
  176.             }
  177.         }
  178.         if(seg.flags.rst){    /* p 67 */
  179.             if(seg.flags.ack){
  180.                 /* The ack must be acceptable since we just checked it.
  181.                  * This is how the remote side refuses connect requests.
  182.                  */
  183.                 close_self(tcb,RESET);
  184.             }
  185.             free_p(bp);
  186.             return;
  187.         }
  188.         /* (Security check skipped here) */
  189.         /* Check incoming precedence; it must match if there's an ACK */
  190.         if(seg.flags.ack && PREC(ip->tos) != PREC(tcb->tos)){
  191.             free_p(bp);
  192.             reset(ip,&seg);
  193.             return;
  194.         }
  195.         if(seg.flags.syn){
  196.             proc_syn(tcb,ip->tos,&seg);
  197.             if(seg.flags.ack){
  198.                 /* Our SYN has been acked, otherwise the ACK
  199.                  * wouldn't have been valid.
  200.                  */
  201.                 update(tcb,&seg,length);
  202.                 setstate(tcb,TCP_ESTABLISHED);
  203.             } else {
  204.                 setstate(tcb,TCP_SYN_RECEIVED);
  205.             }
  206.             if(length != 0 || seg.flags.fin) {
  207.                 break;        /* Continue processing if there's more */
  208.             }
  209.             tcp_output(tcb);
  210.         } else {
  211.             free_p(bp);    /* Ignore if neither SYN or RST is set */
  212.         }
  213.         return;
  214.     }
  215.     /* We reach this point directly in any synchronized state. Note that
  216.      * if we fell through from LISTEN or SYN_SENT processing because of a
  217.      * data-bearing SYN, window trimming and sequence testing "cannot fail".
  218.      */
  219.  
  220.     /* Trim segment to fit receive window. */
  221.     if(trim(tcb,&seg,&bp,&length) == -1){
  222.         /* Segment is unacceptable */
  223.         if(!seg.flags.rst){    /* NEVER answer RSTs */
  224.             /* In SYN_RECEIVED state, answer a retransmitted SYN 
  225.              * with a retransmitted SYN/ACK.
  226.              */
  227.             if(tcb->state == TCP_SYN_RECEIVED)
  228.                 tcb->snd.ptr = tcb->snd.una;
  229.             tcb->flags.force = 1;
  230.             tcp_output(tcb);
  231.         }
  232.         return;
  233.     }
  234.     /* If segment isn't the next one expected, and there's data
  235.      * or flags associated with it, put it on the resequencing
  236.      * queue, ACK it and return.
  237.      *
  238.      * Processing the ACK in an out-of-sequence segment without
  239.      * flags or data should be safe, however.
  240.      */
  241.     if(seg.seq != tcb->rcv.nxt
  242.      && (length != 0 || seg.flags.syn || seg.flags.fin)){
  243.         add_reseq(tcb,ip->tos,&seg,bp,length);
  244.         tcb->flags.force = 1;
  245.         tcp_output(tcb);
  246.         return;
  247.     }
  248.     /* This loop first processes the current segment, and then
  249.      * repeats if it can process the resequencing queue.
  250.      */
  251.     for(;;){
  252.         /* We reach this point with an acceptable segment; all data and flags
  253.          * are in the window, and the starting sequence number equals rcv.nxt
  254.          * (p. 70)
  255.          */    
  256.         if(seg.flags.rst){
  257.             if(tcb->state == TCP_SYN_RECEIVED
  258.              && !tcb->flags.clone && !tcb->flags.active){
  259.                 /* Go back to listen state only if this was
  260.                  * not a cloned or active server TCB
  261.                  */
  262.                 setstate(tcb,TCP_LISTEN);
  263.             } else {
  264.                 close_self(tcb,RESET);
  265.             }
  266.             free_p(bp);
  267.             return;
  268.         }
  269.         /* (Security check skipped here) p. 71 */
  270.         /* Check for precedence mismatch or erroneous extra SYN */
  271.         if(PREC(ip->tos) != PREC(tcb->tos) || seg.flags.syn){
  272.             free_p(bp);
  273.             reset(ip,&seg);
  274.             return;
  275.         }
  276.         /* Check ack field p. 72 */
  277.         if(!seg.flags.ack){
  278.             free_p(bp);    /* All segments after synchronization must have ACK */
  279.             return;
  280.         }
  281.         /* Process ACK */
  282.         switch(tcb->state){
  283.         case TCP_SYN_RECEIVED:
  284.             if(seq_within(seg.ack,tcb->snd.una+1,tcb->snd.nxt)){
  285.                 update(tcb,&seg,length);
  286.                 setstate(tcb,TCP_ESTABLISHED);
  287.             } else {
  288.                 free_p(bp);
  289.                 reset(ip,&seg);
  290.                 return;
  291.             }
  292.             break;
  293.         case TCP_ESTABLISHED:
  294.         case TCP_CLOSE_WAIT:
  295.             update(tcb,&seg,length);
  296.             break;
  297.         case TCP_FINWAIT1:    /* p. 73 */
  298.             update(tcb,&seg,length);
  299.             if(tcb->sndcnt == 0){
  300.                 /* Our FIN is acknowledged */
  301.                 setstate(tcb,TCP_FINWAIT2);
  302.             }
  303.             break;
  304.         case TCP_FINWAIT2:
  305.             update(tcb,&seg,length);
  306.             break;
  307.         case TCP_CLOSING:
  308.             update(tcb,&seg,length);
  309.             if(tcb->sndcnt == 0){
  310.                 /* Our FIN is acknowledged */
  311.                 setstate(tcb,TCP_TIME_WAIT);
  312.                 set_timer(&tcb->timer,MSL2*1000L);
  313.                 start_timer(&tcb->timer);
  314.             }
  315.             break;
  316.         case TCP_LAST_ACK:
  317.             update(tcb,&seg,length);
  318.             if(tcb->sndcnt == 0){
  319.                 /* Our FIN is acknowledged, close connection */
  320.                 close_self(tcb,NORMAL);
  321.                 return;
  322.             }            
  323.             break;
  324.         case TCP_TIME_WAIT:
  325.             start_timer(&tcb->timer);
  326.             break;
  327.         }
  328.  
  329.         /* (URGent bit processing skipped here) */
  330.  
  331.         /* Process the segment text, if any, beginning at rcv.nxt (p. 74) */
  332.         if(length != 0){
  333.             switch(tcb->state){
  334.             case TCP_SYN_RECEIVED:
  335.             case TCP_ESTABLISHED:
  336.             case TCP_FINWAIT1:
  337.             case TCP_FINWAIT2:
  338.                 /* Place on receive queue */
  339.                 append(&tcb->rcvq,bp);
  340.                 tcb->rcvcnt += length;
  341.                 tcb->rcv.nxt += length;
  342.                 tcb->rcv.wnd -= length;
  343.                 tcb->flags.force = 1;
  344.                 /* Notify user */
  345.                 if(tcb->r_upcall)
  346.                     (*tcb->r_upcall)(tcb,tcb->rcvcnt);
  347.                 break;
  348.             default:
  349.                 /* Ignore segment text */
  350.                 free_p(bp);
  351.                 break;
  352.             }
  353.         }
  354.         /* process FIN bit (p 75) */
  355.         if(seg.flags.fin){
  356.             tcb->flags.force = 1;    /* Always respond with an ACK */
  357.  
  358.             switch(tcb->state){
  359.             case TCP_SYN_RECEIVED:
  360.             case TCP_ESTABLISHED:
  361.                 tcb->rcv.nxt++;
  362.                 setstate(tcb,TCP_CLOSE_WAIT);
  363.                 break;
  364.             case TCP_FINWAIT1:
  365.                 tcb->rcv.nxt++;
  366.                 if(tcb->sndcnt == 0){
  367.                     /* Our FIN has been acked; bypass TCP_CLOSING state */
  368.                     setstate(tcb,TCP_TIME_WAIT);
  369.                     set_timer(&tcb->timer,MSL2*1000L);
  370.                     start_timer(&tcb->timer);
  371.                 } else {
  372.                     setstate(tcb,TCP_CLOSING);
  373.                 }
  374.                 break;
  375.             case TCP_FINWAIT2:
  376.                 tcb->rcv.nxt++;
  377.                 setstate(tcb,TCP_TIME_WAIT);
  378.                 set_timer(&tcb->timer,MSL2*1000L);
  379.                 start_timer(&tcb->timer);
  380.                 break;
  381.             case TCP_CLOSE_WAIT:
  382.             case TCP_CLOSING:
  383.             case TCP_LAST_ACK:
  384.                 break;        /* Ignore */
  385.             case TCP_TIME_WAIT:    /* p 76 */
  386.                 start_timer(&tcb->timer);
  387.                 break;
  388.             }
  389.             /* Call the client again so he can see EOF */
  390.             if(tcb->r_upcall)
  391.                 (*tcb->r_upcall)(tcb,tcb->rcvcnt);
  392.         }
  393.         /* Scan the resequencing queue, looking for a segment we can handle,
  394.          * and freeing all those that are now obsolete.
  395.          */
  396.         while(tcb->reseq != NULLRESEQ && seq_ge(tcb->rcv.nxt,tcb->reseq->seg.seq)){
  397.             get_reseq(tcb,&ip->tos,&seg,&bp,&length);
  398.             if(trim(tcb,&seg,&bp,&length) == 0)
  399.                 goto gotone;
  400.             /* Segment is an old one; trim has freed it */
  401.         }
  402.         break;
  403. gotone:    ;
  404.     }
  405.     tcp_output(tcb);    /* Send any necessary ack */
  406. }
  407.  
  408. /* Process an incoming ICMP response */
  409. void
  410. tcp_icmp(icsource,source,dest,type,code,bpp)
  411. int32 icsource;            /* Sender of ICMP message (not used) */
  412. int32 source;            /* Original IP datagram source (i.e. us) */
  413. int32 dest;            /* Original IP datagram dest (i.e., them) */
  414. char type,code;            /* ICMP error codes */
  415. struct mbuf **bpp;        /* First 8 bytes of TCP header */
  416. {
  417.     struct tcp seg;
  418.     struct connection conn;
  419.     register struct tcb *tcb;
  420.  
  421.     /* Extract the socket info from the returned TCP header fragment
  422.      * Note that since this is a datagram we sent, the source fields
  423.      * refer to the local side.
  424.      */
  425.     ntohtcp(&seg,bpp);
  426.     conn.local.port = seg.source;
  427.     conn.remote.port = seg.dest;
  428.     conn.local.address = source;
  429.     conn.remote.address = dest;
  430.     if((tcb = lookup_tcb(&conn)) == NULLTCB)
  431.         return;    /* Unknown connection, ignore */
  432.  
  433.     /* Verify that the sequence number in the returned segment corresponds
  434.      * to something currently unacknowledged. If not, it can safely
  435.      * be ignored.
  436.      */
  437.     if(!seq_within(seg.seq,tcb->snd.una,tcb->snd.nxt))
  438.         return;
  439.  
  440.     /* Destination Unreachable and Time Exceeded messages never kill a
  441.      * connection; the info is merely saved for future reference.
  442.      */
  443.     switch(uchar(type)){
  444.     case ICMP_DEST_UNREACH:
  445.     case ICMP_TIME_EXCEED:
  446.         tcb->type = type;
  447.         tcb->code = code;
  448.         break;
  449.     case ICMP_QUENCH:
  450.         /* Source quench; cut the congestion window in half,
  451.          * but don't let it go below one packet
  452.          */
  453.         tcb->cwind /= 2;
  454.         tcb->cwind = max(tcb->mss,tcb->cwind);
  455.         break;
  456.     }
  457. }
  458. /* Send an acceptable reset (RST) response for this segment
  459.  * The RST reply is composed in place on the input segment
  460.  */
  461. void
  462. reset(ip,seg)
  463. struct ip *ip;            /* Offending IP header */
  464. register struct tcp *seg;    /* Offending TCP header */
  465. {
  466.     struct mbuf *hbp;
  467.     struct pseudo_header ph;
  468.     int16 tmp;
  469.  
  470.     if(seg->flags.rst)
  471.         return;    /* Never send an RST in response to an RST */
  472.  
  473.     /* Compose the RST IP pseudo-header, swapping addresses */
  474.     ph.source = ip->dest;
  475.     ph.dest = ip->source;
  476.     ph.protocol = TCP_PTCL;
  477.     ph.length = TCPLEN;
  478.  
  479.     /* Swap port numbers */
  480.     tmp = seg->source;
  481.     seg->source = seg->dest;
  482.     seg->dest = tmp;
  483.  
  484.     if(seg->flags.ack){
  485.         /* This reset is being sent to clear a half-open connection.
  486.          * Set the sequence number of the RST to the incoming ACK
  487.          * so it will be acceptable.
  488.          */
  489.         seg->flags.ack = 0;
  490.         seg->seq = seg->ack;
  491.         seg->ack = 0;
  492.     } else {
  493.         /* We're rejecting a connect request (SYN) from TCP_LISTEN state
  494.          * so we have to "acknowledge" their SYN.
  495.          */
  496.         seg->flags.ack = 1;
  497.         seg->ack = seg->seq;
  498.         seg->seq = 0;
  499.         if(seg->flags.syn)
  500.             seg->ack++;
  501.     }
  502.     /* Set remaining parts of packet */
  503.     seg->flags.urg = 0;
  504.     seg->flags.psh = 0;
  505.     seg->flags.rst = 1;
  506.     seg->flags.syn = 0;
  507.     seg->flags.fin = 0;
  508.     seg->wnd = 0;
  509.     seg->up = 0;
  510.     seg->mss = 0;
  511.     seg->optlen = 0;
  512.     if((hbp = htontcp(seg,NULLBUF,&ph)) == NULLBUF)
  513.         return;
  514.     /* Ship it out (note swap of addresses) */
  515.     ip_send(ip->dest,ip->source,TCP_PTCL,ip->tos,0,hbp,ph.length,0,0);
  516.     tcpOutRsts++;
  517. }
  518.  
  519. /* Process an incoming acknowledgement and window indication.
  520.  * From page 72.
  521.  */
  522. static void
  523. update(tcb,seg,length)
  524. register struct tcb *tcb;
  525. register struct tcp *seg;
  526. int16 length;
  527. {
  528.     int16 acked;
  529.     int16 expand;
  530.  
  531.     acked = 0;
  532.     if(seq_gt(seg->ack,tcb->snd.nxt)){
  533.         tcb->flags.force = 1;    /* Acks something not yet sent */
  534.         return;
  535.     }
  536.     /* Decide if we need to do a window update.
  537.      * This is always checked whenever a legal ACK is received,
  538.      * even if it doesn't actually acknowledge anything,
  539.      * because it might be a spontaneous window reopening.
  540.      */
  541.     if(seq_gt(seg->seq,tcb->snd.wl1) || ((seg->seq == tcb->snd.wl1) 
  542.      && seq_ge(seg->ack,tcb->snd.wl2))){
  543.         /* If the window had been closed, crank back the
  544.          * send pointer so we'll immediately resume transmission.
  545.          * Otherwise we'd have to wait until the next probe.
  546.          */
  547.         if(tcb->snd.wnd == 0 && seg->wnd != 0)
  548.             tcb->snd.ptr = tcb->snd.una;
  549.         tcb->snd.wnd = seg->wnd;
  550.         tcb->snd.wl1 = seg->seq;
  551.         tcb->snd.wl2 = seg->ack;
  552.     }
  553.     /* See if anything new is being acknowledged */
  554.     if(!seq_gt(seg->ack,tcb->snd.una)){
  555.         if(seg->ack != tcb->snd.una)
  556.             return;    /* Old ack, ignore */
  557.  
  558.         if(length != 0 || seg->flags.syn || seg->flags.fin)
  559.             return;    /* Nothing acked, but there is data */
  560.  
  561.         /* Van Jacobson "fast recovery" code */
  562.         if(++tcb->dupacks == TCPDUPACKS){
  563.             /* We've had a burst of do-nothing acks, so
  564.              * we almost certainly lost a packet.
  565.              * Resend it now to avoid a timeout. (This is
  566.              * Van Jacobson's 'quick recovery' algorithm.)
  567.              */
  568.             int32 ptrsave;
  569.  
  570.             /* Knock the threshold down just as though
  571.              * this were a timeout, since we've had
  572.              * network congestion.
  573.              */
  574.             tcb->ssthresh = tcb->cwind/2;
  575.             tcb->ssthresh = max(tcb->ssthresh,tcb->mss);
  576.  
  577.             /* Manipulate the machinery in tcp_output() to
  578.              * retransmit just the missing packet
  579.              */
  580.             ptrsave = tcb->snd.ptr;
  581.             tcb->snd.ptr = tcb->snd.una;
  582.             tcb->cwind = tcb->mss;
  583.             tcp_output(tcb);
  584.             tcb->snd.ptr = ptrsave;
  585.  
  586.             /* "Inflate" the congestion window, pretending as
  587.              * though the duplicate acks were normally acking
  588.              * the packets beyond the one that was lost.
  589.              */
  590.             tcb->cwind = tcb->ssthresh + TCPDUPACKS*tcb->mss;
  591.         } else if(tcb->dupacks > TCPDUPACKS){
  592.             /* Continue to inflate the congestion window
  593.              * until the acks finally get "unstuck".
  594.              */
  595.             tcb->cwind += tcb->mss;
  596.         }
  597.         return;
  598.     }
  599.     if(tcb->dupacks >= TCPDUPACKS && tcb->cwind > tcb->ssthresh){
  600.         /* The acks have finally gotten "unstuck". So now we
  601.          * can "deflate" the congestion window, i.e. take it
  602.          * back down to where it would be after slow start
  603.          * finishes.
  604.          */
  605.         tcb->cwind = tcb->ssthresh;
  606.     }
  607.     tcb->dupacks = 0;
  608.  
  609.     /* We're here, so the ACK must have actually acked something */
  610.     acked = seg->ack - tcb->snd.una;
  611.  
  612.     /* Expand congestion window if not already at limit and if
  613.      * this packet wasn't retransmitted
  614.      */
  615.     if(tcb->cwind < tcb->snd.wnd && !tcb->flags.retran){
  616.         if(tcb->cwind < tcb->ssthresh){
  617.             /* Still doing slow start/CUTE, expand by amount acked */
  618.             expand = min(acked,tcb->mss);
  619.         } else {
  620.             /* Steady-state test of extra path capacity */
  621.             expand = ((long)tcb->mss * tcb->mss) / tcb->cwind;
  622.         }
  623.         /* Guard against arithmetic overflow */
  624.         if(tcb->cwind + expand < tcb->cwind)
  625.             expand = MAXINT16 - tcb->cwind;
  626.  
  627.         /* Don't expand beyond the offered window */
  628.         if(tcb->cwind + expand > tcb->snd.wnd)
  629.             expand = tcb->snd.wnd - tcb->cwind;
  630.  
  631.         if(expand != 0){
  632. #ifdef    notdef
  633.             /* Kick up the mean deviation estimate to prevent
  634.              * unnecessary retransmission should we already be
  635.              * bandwidth limited
  636.              */
  637.             tcb->mdev += ((long)tcb->srtt * expand) / tcb->cwind;
  638. #endif
  639.             tcb->cwind += expand;
  640.         }
  641.     }
  642.     /* Round trip time estimation */
  643.     if(tcb->flags.rtt_run && seq_ge(seg->ack,tcb->rttseq)){
  644.         /* A timed sequence number has been acked */
  645.         tcb->flags.rtt_run = 0;
  646.         if(!(tcb->flags.retran)){
  647.             int32 rtt;    /* measured round trip time */
  648.             int32 abserr;    /* abs(rtt - srtt) */
  649.  
  650.             /* This packet was sent only once and now
  651.              * it's been acked, so process the round trip time
  652.              */
  653.             rtt = msclock() - tcb->rtt_time;
  654.  
  655.             abserr = (rtt > tcb->srtt) ? rtt - tcb->srtt : tcb->srtt - rtt;
  656.             /* Run SRTT and MDEV integrators, with rounding */
  657.             tcb->srtt = ((AGAIN-1)*tcb->srtt + rtt + (AGAIN/2)) >> LAGAIN;
  658.             tcb->mdev = ((DGAIN-1)*tcb->mdev + abserr + (DGAIN/2)) >> LDGAIN;
  659.  
  660.             rtt_add(tcb->conn.remote.address,rtt);
  661.             /* Reset the backoff level */
  662.             tcb->backoff = 0;
  663.         }
  664.     }
  665.     tcb->sndcnt -= acked;    /* Update virtual byte count on snd queue */
  666.     tcb->snd.una = seg->ack;
  667.  
  668.     /* If we're waiting for an ack of our SYN, note it and adjust count */
  669.     if(!(tcb->flags.synack)){
  670.         tcb->flags.synack = 1;
  671.         acked--;    /* One less byte to pull from real snd queue */
  672.     }
  673.     /* Remove acknowledged bytes from the send queue and update the
  674.      * unacknowledged pointer. If a FIN is being acked,
  675.      * pullup won't be able to remove it from the queue, but that
  676.      * causes no harm.
  677.      */
  678.     pullup(&tcb->sndq,NULLCHAR,acked);
  679.  
  680.     /* Stop retransmission timer, but restart it if there is still
  681.      * unacknowledged data. If there is no more unacked data,
  682.      * the transmitter has gone at least momentarily idle, so
  683.      * record the time for the VJ restart-slowstart rule.
  684.      */    
  685.     stop_timer(&tcb->timer);
  686.     if(tcb->snd.una != tcb->snd.nxt)
  687.         start_timer(&tcb->timer);
  688.     else
  689.         tcb->lastactive = msclock();
  690.  
  691.     /* If retransmissions have been occurring, make sure the
  692.      * send pointer doesn't repeat ancient history
  693.      */
  694.     if(seq_lt(tcb->snd.ptr,tcb->snd.una))
  695.         tcb->snd.ptr = tcb->snd.una;
  696.  
  697.     /* Clear the retransmission flag since the oldest
  698.      * unacknowledged segment (the only one that is ever retransmitted)
  699.      * has now been acked.
  700.      */
  701.     tcb->flags.retran = 0;
  702.  
  703.     /* If outgoing data was acked, notify the user so he can send more
  704.      * unless we've already sent a FIN.
  705.      */
  706.     if(acked != 0 && tcb->t_upcall
  707.      && (tcb->state == TCP_ESTABLISHED || tcb->state == TCP_CLOSE_WAIT)){
  708.         (*tcb->t_upcall)(tcb,tcb->window - tcb->sndcnt);
  709.     }
  710. }
  711.  
  712. /* Determine if the given sequence number is in our receiver window.
  713.  * NB: must not be used when window is closed!
  714.  */
  715. static
  716. int
  717. in_window(tcb,seq)
  718. struct tcb *tcb;
  719. int32 seq;
  720. {
  721.     return seq_within(seq,tcb->rcv.nxt,(int32)(tcb->rcv.nxt+tcb->rcv.wnd-1));
  722. }
  723.  
  724. /* Process an incoming SYN */
  725. static void
  726. proc_syn(tcb,tos,seg)
  727. register struct tcb *tcb;
  728. char tos;
  729. struct tcp *seg;
  730. {
  731.     int16 mtu;
  732.     struct tcp_rtt *tp;
  733.  
  734.     tcb->flags.force = 1;    /* Always send a response */
  735.  
  736.     /* Note: It's not specified in RFC 793, but SND.WL1 and
  737.      * SND.WND are initialized here since it's possible for the
  738.      * window update routine in update() to fail depending on the
  739.      * IRS if they are left unitialized.
  740.      */
  741.     /* Check incoming precedence and increase if higher */
  742.     if(PREC(tos) > PREC(tcb->tos))
  743.         tcb->tos = tos;
  744.     tcb->rcv.nxt = seg->seq + 1;    /* p 68 */
  745.     tcb->snd.wl1 = tcb->irs = seg->seq;
  746.     tcb->snd.wnd = seg->wnd;
  747.     if(seg->mss != 0)
  748.         tcb->mss = seg->mss;
  749.     /* Check the MTU of the interface we'll use to reach this guy
  750.      * and lower the MSS so that unnecessary fragmentation won't occur
  751.      */
  752.     if((mtu = ip_mtu(tcb->conn.remote.address)) != 0){
  753.         /* Allow space for the TCP and IP headers */
  754.         mtu -= TCPLEN + IPLEN;
  755.         tcb->cwind = tcb->mss = min(mtu,tcb->mss);
  756.     }
  757.     /* See if there's round-trip time experience */
  758.     if((tp = rtt_get(tcb->conn.remote.address)) != NULLRTT){
  759.         tcb->srtt = tp->srtt;
  760.         tcb->mdev = tp->mdev;
  761.     }
  762. }
  763.  
  764. /* Generate an initial sequence number and put a SYN on the send queue */
  765. void
  766. send_syn(tcb)
  767. register struct tcb *tcb;
  768. {
  769.     tcb->iss = geniss();
  770.     tcb->rttseq = tcb->snd.wl2 = tcb->snd.una = tcb->iss;
  771.     tcb->snd.ptr = tcb->snd.nxt = tcb->rttseq;
  772.     tcb->sndcnt++;
  773.     tcb->flags.force = 1;
  774. }
  775.  
  776. /* Add an entry to the resequencing queue in the proper place */
  777. static void
  778. add_reseq(tcb,tos,seg,bp,length)
  779. struct tcb *tcb;
  780. char tos;
  781. struct tcp *seg;
  782. struct mbuf *bp;
  783. int16 length;
  784. {
  785.     register struct reseq *rp,*rp1;
  786.  
  787.     /* Allocate reassembly descriptor */
  788.     if((rp = (struct reseq *)malloc(sizeof (struct reseq))) == NULLRESEQ){
  789.         /* No space, toss on floor */
  790.         free_p(bp);
  791.         return;
  792.     }
  793.     ASSIGN(rp->seg,*seg);
  794.     rp->tos = tos;
  795.     rp->bp = bp;
  796.     rp->length = length;
  797.  
  798.     /* Place on reassembly list sorting by starting seq number */
  799.     rp1 = tcb->reseq;
  800.     if(rp1 == NULLRESEQ || seq_lt(seg->seq,rp1->seg.seq)){
  801.         /* Either the list is empty, or we're less than all other
  802.          * entries; insert at beginning.
  803.          */
  804.         rp->next = rp1;
  805.         tcb->reseq = rp;
  806.     } else {
  807.         /* Find the last entry less than us */
  808.         for(;;){
  809.             if(rp1->next == NULLRESEQ || seq_lt(seg->seq,rp1->next->seg.seq)){
  810.                 /* We belong just after this one */
  811.                 rp->next = rp1->next;
  812.                 rp1->next = rp;
  813.                 break;
  814.             }
  815.             rp1 = rp1->next;
  816.         }
  817.     }
  818. }
  819.  
  820. /* Fetch the first entry off the resequencing queue */
  821. static void
  822. get_reseq(tcb,tos,seg,bp,length)
  823. register struct tcb *tcb;
  824. char *tos;
  825. struct tcp *seg;
  826. struct mbuf **bp;
  827. int16 *length;
  828. {
  829.     register struct reseq *rp;
  830.  
  831.     if((rp = tcb->reseq) == NULLRESEQ)
  832.         return;
  833.  
  834.     tcb->reseq = rp->next;
  835.  
  836.     *tos = rp->tos;
  837.     ASSIGN(*seg,rp->seg);
  838.     *bp = rp->bp;
  839.     *length = rp->length;
  840.     free((char *)rp);
  841. }
  842.  
  843. /* Trim segment to fit window. Return 0 if OK, -1 if segment is
  844.  * unacceptable.
  845.  */
  846. static int
  847. trim(tcb,seg,bpp,length)
  848. register struct tcb *tcb;
  849. register struct tcp *seg;
  850. struct mbuf **bpp;
  851. int16 *length;
  852. {
  853.     long dupcnt,excess;
  854.     int16 len;        /* Segment length including flags */
  855.     char accept = 0;
  856.  
  857.     len = *length;
  858.     if(seg->flags.syn)
  859.         len++;
  860.     if(seg->flags.fin)
  861.         len++;
  862.  
  863.     /* Acceptability tests */
  864.     if(tcb->rcv.wnd == 0){
  865.         /* Only in-order, zero-length segments are acceptable when
  866.          * our window is closed.
  867.          */
  868.         if(seg->seq == tcb->rcv.nxt && len == 0){
  869.             return 0;    /* Acceptable, no trimming needed */
  870.         }
  871.     } else {
  872.         /* Some part of the segment must be in the window */
  873.         if(in_window(tcb,seg->seq)){
  874.             accept++;    /* Beginning is */
  875.         } else if(len != 0){
  876.             if(in_window(tcb,(int32)(seg->seq+len-1)) || /* End is */
  877.              seq_within(tcb->rcv.nxt,seg->seq,(int32)(seg->seq+len-1))){ /* Straddles */
  878.                 accept++;
  879.             }
  880.         }
  881.     }
  882.     if(!accept){
  883.         tcb->rerecv += len;    /* Assume all of it was a duplicate */
  884.         free_p(*bpp);
  885.         return -1;
  886.     }
  887.     if((dupcnt = tcb->rcv.nxt - seg->seq) > 0){
  888.         tcb->rerecv += dupcnt;
  889.         /* Trim off SYN if present */
  890.         if(seg->flags.syn){
  891.             /* SYN is before first data byte */
  892.             seg->flags.syn = 0;
  893.             seg->seq++;
  894.             dupcnt--;
  895.         }
  896.         if(dupcnt > 0){
  897.             pullup(bpp,NULLCHAR,(int16)dupcnt);
  898.             seg->seq += dupcnt;
  899.             *length -= dupcnt;
  900.         }
  901.     }
  902.     if((excess = seg->seq + *length - (tcb->rcv.nxt + tcb->rcv.wnd)) > 0){
  903.         tcb->rerecv += excess;
  904.         /* Trim right edge */
  905.         *length -= excess;
  906.         trim_mbuf(bpp,*length);
  907.         seg->flags.fin = 0;    /* FIN follows last data byte */
  908.     }
  909.     return 0;
  910. }
  911.